package abel.wlmr.model.unit;

import java.time.DateTimeException;

import abel.util.StdBcdNumber;
import abel.wlmr.model.WlmrBaseUnit;
import abel.wlmr.model.WlmrException;
import io.netty.buffer.ByteBuf;

/**
 * B.5.11.1.3.4 日冻结类数据时标Td_d
 * 日冻结类数据时标 Td_d 的长度为 3 个字节，定义见表 B.119。
 * 表B.119 日冻结类数据时标数据格式
 * 数据内容 数据格式 字节数
 * 日月年 见附录 C.20 3
 * 日冻结数据是指终端在每日 24 点时刻所冻结的数据，其中由抄表得到的数据是日末 24 点时刻所抄
 * 回冻结的远传表数据。
 * 抄表日冻结数据是指终端按主站设置的终端抄表日（见本附录 B.5.4.1.3.13） 日末 24 点时刻所抄回冻
 * 结的远传表数据
 * 
 * @author Abel
 *
 */
public class AfnSecondF409DownUnit extends WlmrBaseUnit {
    private static final short FIXED_LENGTH = 3;

    /**
     * 日冻结类数据时标 Td_d 见本附录 B.5.13.1.3.4 日月年 3
     * 日月年 见附录 C.20 3
     */
    private StdBcdNumber frozeTdd;

    public AfnSecondF409DownUnit() {
        super();
    }

    public AfnSecondF409DownUnit(short guessedLen) {
        super(guessedLen);
    }

    /* (non-Javadoc)
     * @see abel.wlmr.model.AppUnitBody#appendBuf(io.netty.buffer.ByteBuf)
     */
    @Override
    public ByteBuf appendBuf(ByteBuf buf) {
        if (frozeTdd == null || frozeTdd.length() != 3) {
            throw new IllegalArgumentException("froze tdd should be 3 bcd long");
        }

        buf.writeBytes(frozeTdd.toBytes());

        return buf;
    }

    /* (non-Javadoc)
     * @see abel.wlmr.model.AppUnitBody#parseBuf(io.netty.buffer.ByteBuf)
     */
    @Override
    public int parseBuf(ByteBuf buf) throws WlmrException {
        if (checkBuffer(buf) < 0) {
            return -1;
        }

        frozeTdd = new StdBcdNumber();
        frozeTdd.populateBytes(buf, 3);

        try {
            frozeTdd.toMeterC20Joda();
        } catch (DateTimeException e) {
            throw new WlmrException("invalid froze-tdd in C.20", e);
        }

        return FIXED_LENGTH;
    }

    /* (non-Javadoc)
     * @see abel.wlmr.model.WlmrDataPart#getMinLength()
     */
    @Override
    public int getMinLength() {
        return FIXED_LENGTH;
    }

    /* (non-Javadoc)
     * @see abel.wlmr.model.AppUnitBody#getFinalLen()
     */
    @Override
    public short getFinalLen() {
        return FIXED_LENGTH;
    }

    /* (non-Javadoc)
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return String.format("{frozeTdd:%s}", frozeTdd);
    }

    /**
     * 日冻结类数据时标 Td_d 见本附录 B.5.13.1.3.4 日月年 3
     * 日月年 见附录 C.20 3
     * 
     * @return the frozeTdd
     */
    public StdBcdNumber getFrozeTdd() {
        return frozeTdd;
    }

    /**
     * 日冻结类数据时标 Td_d 见本附录 B.5.13.1.3.4 日月年 3
     * 日月年 见附录 C.20 3
     * 
     * @param frozeTdd
     *            the frozeTdd to set
     */
    public void setFrozeTdd(StdBcdNumber frozeTdd) {
        if (frozeTdd == null || frozeTdd.length() != 3) {
            throw new IllegalArgumentException("froze tdd should be 3 bcd long");
        }

        // may throw IAE
        frozeTdd.toMeterC20Joda();
        this.frozeTdd = frozeTdd;
    }
}
